package com.example.service.impl;

import com.example.dto.ApiResponse;
import com.example.entity.UserSession;
import com.example.mapper.UserSessionMapper;
import com.example.service.UserSessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class UserSessionServiceImpl implements UserSessionService {

    @Autowired
    private UserSessionMapper userSessionMapper;

    @Value("${session.max-concurrent-sessions:3}")
    private int maxConcurrentSessions;

    @Value("${session.expiry-minutes:30}")
    private int sessionExpiryMinutes;

    @Override
    public UserSession createSession(Long userId, String token, String deviceInfo, String ipAddress) {
        // 检查并清理过期会话
        cleanupExpiredSessions();

        // 检查当前活跃会话数
        int activeSessions = userSessionMapper.countActiveSessions(userId);
        if (activeSessions >= maxConcurrentSessions) {
            // 如果超过最大会话数，使最早的会话失效
            List<UserSession> sessions = userSessionMapper.findActiveSessionsByUserId(userId);
            if (!sessions.isEmpty()) {
                UserSession oldestSession = sessions.get(0);
                invalidateSession(oldestSession.getToken());
            }
        }

        // 创建新会话
        UserSession session = new UserSession();
        session.setUserId(userId);
        session.setToken(token);
        session.setDeviceInfo(deviceInfo);
        session.setIpAddress(ipAddress);
        session.setLoginTime(LocalDateTime.now());
        session.setLastAccessTime(LocalDateTime.now());
        session.setExpiryTime(LocalDateTime.now().plusMinutes(sessionExpiryMinutes));
        session.setActive(true);

        userSessionMapper.insert(session);
        return session;
    }

    @Override
    public boolean validateSession(String token) {
        UserSession session = userSessionMapper.findByToken(token);
        if (session == null || !session.getActive() ||
            session.getExpiryTime().isBefore(LocalDateTime.now())) {
            return false;
        }
        updateLastAccessTime(token);
        return true;
    }

    @Override
    public void updateLastAccessTime(String token) {
        userSessionMapper.updateLastAccessTime(token, LocalDateTime.now());
    }

    @Override
    public List<UserSession> getUserActiveSessions(Long userId) {
        return userSessionMapper.findActiveSessionsByUserId(userId);
    }

    @Override
    public ApiResponse<?> invalidateSession(String token) {
        int result = userSessionMapper.invalidateSession(token);
        if (result > 0) {
            return ApiResponse.success("Session invalidated successfully");
        }
        return ApiResponse.error("Failed to invalidate session");
    }

    @Override
    public ApiResponse<?> invalidateAllUserSessions(Long userId) {
        int result = userSessionMapper.invalidateAllUserSessions(userId);
        if (result > 0) {
            return ApiResponse.success("All user sessions invalidated successfully");
        }
        return ApiResponse.error("Failed to invalidate user sessions");
    }

    @Override
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void cleanupExpiredSessions() {
        LocalDateTime now = LocalDateTime.now();
        userSessionMapper.update(null,
            new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<UserSession>()
                .set("active", false)
                .eq("active", true)
                .lt("expiry_time", now));
    }

    @Override
    public UserSession getSessionByToken(String token) {
        return userSessionMapper.findByToken(token);
    }
}